/* $RCSFile: ADNLicense.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.ServerControls/LicenceControls/ADNLicense.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:30  christian.surieux
 *   Added Log to All cs files
 */

// ADNLicense.cs
// Server Controls and Components
//

using System;
using System.Diagnostics; 
using System.Threading;
using System.ComponentModel;
using System.Globalization;

namespace ADNCRM.ServerControls 
{

   	#region Base TraceSwitch classe that define some usefull properties
	public class ADNTraceSwitch0 : TraceSwitch
	{
        public ADNTraceSwitch0()
            : base("DefaultTrace0","Trace Switch for Default methods")
        { }
        public ADNTraceSwitch0(string nm, string des)
            : base(nm, des)
        { }
        public string Info{ get{ return string.Format("{0}-{1}",DisplayName,Level);}}
	}
	#endregion Base TraceSwitch classe that define some usefull properties

    
    #region TraceSwitch for License

    public class LicenseTraceSwitch  
    {
        static public ADNTraceSwitch0 Sw = new ADNTraceSwitch0("LicenseTrace", "Trace Switch for licensing system");
    }
    #endregion TraceSwitch for License

    public delegate int ExternalLicenseCountHandler(ADNBaseLicense lic);
    
    public class ADNBaseLicense : License 
	{

		private Type _type;
		private string _key;

        public static event ExternalLicenseCountHandler LicenseCountEvent;

        public static bool IsExternalLicenseCountEventOk()
        {
            if ( LicenseTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNBaseLicense IsExternalLicenseCountEventOk LicenseCountEvent != null: {0}", (LicenseCountEvent != null)),LicenseTraceSwitch.Sw.Info);
            if (LicenseCountEvent != null)
                return true;
            return false;
        }

        public static int OnExternalLicenseCountEvent(ADNBaseLicense lic)
        {
            if ( LicenseTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNBaseLicense OnExternalLicenseCountEvent Lic: {0}", lic),LicenseTraceSwitch.Sw.Info);
            int nb = -1;
            if (LicenseCountEvent != null)
            {
                if ( LicenseTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNBaseLicense OnExternalLicenseCountEvent Calling: {0}", LicenseCountEvent.Target),LicenseTraceSwitch.Sw.Info);
                nb = LicenseCountEvent(lic);
                if ( LicenseTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNBaseLicense OnExternalLicenseCountEvent ret: {0}", nb),LicenseTraceSwitch.Sw.Info);
            }
            return nb;
        }

		public ADNBaseLicense(Type type, string key) 
		{
			_type = type;
			_key = key;
            if ( LicenseTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNBaseLicense constructor Type: {0}, Key: {1}", type,key),LicenseTraceSwitch.Sw.Info);
		}

		public override string LicenseKey 
		{
			get 
			{
				return _key;
			}
		}

		public Type LicensedType 
		{
			get 
			{
				return _type;
			}
		}

        public virtual string Info
        {
            get
            {
                return _key;
            }
        }

        public virtual bool IsValid
        {
            get
            {
                return true;
            }
        }

		public override void Dispose() 
		{
		}
	}


	public class ADNEncryptedLicense : ADNBaseLicense 
	{
        public enum RightsCheckType {NoCheck=0,FixUserNumberLimit=1,Unlimited=2,CRMLimited};
        public enum LicenseType { Demo = 1, Full = 2, TimeLimited = 3, RunLimited = 4 };

        
        private string	_LicensingVersion	=	null;
		private string	_product			=	null;
		private string	_assembly			=	null;
		private string	_version			=	null;
		private string	_usageType		    =	"Demo";
		private string	_rights				=	"NoRights";
		private string	_date				=	null;
		private string	_company			=	null;
		private string	_PIN				=	null;
		private int		_monthsLimit		=	0;
        private DateTime _dateStart         =   DateTime.MinValue;
        private DateTime _dateLimit         =   DateTime.Now;
		private int		_usageLimit			=	0;
        private int _usageCount             =   0;
        private int _NbUsers                =   0;

        private RightsCheckType _RightCheck  =   RightsCheckType.NoCheck;
        private LicenseType _LicenceCheck    =   LicenseType.Demo;

        public RightsCheckType RightCheck 
		{
			get{	return _RightCheck;}
		}
        public LicenseType LicenceCheck 
		{
            get { return _LicenceCheck; }
		}

        public DateTime DateStart
        {
            get { return _dateStart; }
        }
        public DateTime DateLimit
        {
            get { return _dateLimit; }
        }

		public	int	UsageLimit
		{
			get{	return _usageLimit;}
		}

        public int UsageCount
        {
            get { return _usageCount; }
        }

        public int NbUsers
        {
            get { return _NbUsers; }
        }

        public string Product
		{
			get{	return _product;}
		}
		
		public string	Company
		{
			get{	return _company;}
		}
		
		public string	AssemblyName
		{
			get{	return _assembly;}
		}
		public string	AssemblyVersion
		{
			get{	return _version;}
		}

		public string	UsageType
		{
			get{	return _usageType;}
		}

		public bool	IsDemo
		{
			get{	return (_usageType.IndexOf("demo",StringComparison.InvariantCultureIgnoreCase) != -1);}
		}

		public string	Rights
		{
			get{	return _rights;}
		}

		public string	PIN
		{
			get{	return _PIN;}
		}

        public override string Info
        {
            get
            {
                string nfo              =   string.Empty;
                const string fmt0       =   "{0} Product : {1}<br />License : {2}<br />Rights : {3}<br />PIN : {4}<br />NbUsers : {5}";
                string fmt              =   fmt0;
                //CultureInfo ci = Thread.CurrentThread.CurrentUICulture;
                try
                {
                    try
                    {
                        string str      =   AssemblyResourceManager.GetString("ADNCRM_LICENSE_FMT");
                        if (!string.IsNullOrEmpty(str))
                            fmt         =   str;
                    }
                    catch (Exception ex)
                    {
                        if ( LicenseTraceSwitch.Sw.TraceError )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]ADNEncryptedLicense Info format string ex: {0}", ex),LicenseTraceSwitch.Sw.Info);
                    }
                    string strUsage     =   UsageType;
                    switch (_LicenceCheck)
                    {
                        case  LicenseType.RunLimited:
                            strUsage    =   string.Format("{0} {1} :: {2}", UsageType, UsageCount, UsageLimit);
                            break;
                        case  LicenseType.TimeLimited:
                            strUsage    =   string.Format("{0} {1:d} :: {2:d}", UsageType,DateStart, DateLimit);
                            break;
                        default:
                            break;
                    }
                    nfo                 =   string.Format(fmt, new object[] { Company, Product, strUsage, Rights, PIN,NbUsers });
                }
                catch (Exception ex)
                {
                    string msg          =   string.Format("[E]ADNEncryptedLicense Info Type: {0}, Key: {1}, ex: {2}.",LicensedType, LicenseKey,ex);
                    if ( LicenseTraceSwitch.Sw.TraceError )
                        Trace.WriteLine( msg,LicenseTraceSwitch.Sw.Info);
                    throw new LicenseException(LicensedType, null, msg,ex);
                }

                return nfo;
            }
        }

        public override bool IsValid
        {
            get
            {
                bool Ok             =   false;
                switch (RightCheck)
                {
                    case RightsCheckType.CRMLimited:
                        Ok          =   IsCrmOk;
                        break;
                    case RightsCheckType.FixUserNumberLimit:
                        Ok          =   true;
                        break;
                    case RightsCheckType.Unlimited:
                        Ok          =   true;
                        break;
                    default:
                        Ok          =   true;
                        break;
                }
                if ( Ok )
                    switch(LicenceCheck)
                    {
                        case LicenseType.Demo:
                            Ok      =   true;
                            break;
                        case LicenseType.Full:
                            Ok      =   true;
                            break;
                        case LicenseType.RunLimited:
                            Ok      =   !IsRunExpired;
                            break;
                        case LicenseType.TimeLimited:
                            Ok      =   !IsTimeExpired;
                            break;
                        default:
                            Ok      =   true;
                            break;
                    }
                return Ok;
            }
        }

        public ADNEncryptedLicense(Type type, string key)
            : base(type, key) 
		{

            string[] strArr				=	key.Split(new char[]{';'},StringSplitOptions.RemoveEmptyEntries);

            if (strArr.Length < 10)
            {
                string msg              =   string.Format("[E]ADNEncryptedLicense Ctor Invalid license Key, Type: {0}, Key: {1}", type, key);
                if ( LicenseTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( msg,LicenseTraceSwitch.Sw.Info);
                throw new LicenseException(type, null, msg);
            }
			
			_LicensingVersion			=	strArr[0];
            if (string.IsNullOrEmpty(_LicensingVersion) )
            {
                string msg              =   string.Format("[E]ADNEncryptedLicense Ctor Incorrect license version, Type: {0}, Key: {1}, LicensingVersion: {2}", type, key, _LicensingVersion);   
                if ( LicenseTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( msg,LicenseTraceSwitch.Sw.Info);
                throw new LicenseException(type, null, msg);
            }

			for ( int i=1 ; i < strArr.Length ; i++ )
			{
				string str				    =	strArr[i];
				switch(i)
				{
					case 1:
						_product	        =	str;
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor Product: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
					case 2:
						_assembly	        =	str;
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor Assembly: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
					case 3:
						_version	        =	str;
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor Version: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
					case 4:
						_usageType	        =	str.ToLower(CultureInfo.InvariantCulture);
                        string lusg         =   _usageType;
                        if (lusg.IndexOf("demo",StringComparison.InvariantCultureIgnoreCase) != -1)
                            _LicenceCheck   =  LicenseType.Demo;
                        if (lusg.IndexOf("full",StringComparison.InvariantCultureIgnoreCase) != -1)
                            _LicenceCheck   =     LicenseType.Full;
                        if (lusg.IndexOf("run",StringComparison.InvariantCultureIgnoreCase) != -1)
                            _LicenceCheck   =     LicenseType.RunLimited;
                        if (lusg.IndexOf("time",StringComparison.InvariantCultureIgnoreCase) != -1)
                            _LicenceCheck   =     LicenseType.TimeLimited;
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor UsageType: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
					case 5:
						_rights		        =	str.ToLower(CultureInfo.InvariantCulture);
                        string lrght        =   _rights;
                        if (lrght.IndexOf("fixed",StringComparison.InvariantCultureIgnoreCase) != -1)
                            _RightCheck     =   RightsCheckType.FixUserNumberLimit;
                        if (lrght.IndexOf("unlimited",StringComparison.InvariantCultureIgnoreCase) != -1)
                            _RightCheck     =   RightsCheckType.Unlimited;
                        if (lrght.IndexOf("crm",StringComparison.InvariantCultureIgnoreCase) != -1)
                            _RightCheck     =   RightsCheckType.CRMLimited;
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor Rights: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
					case 6:
						_date		        =	str;
                        try
                        {
                            _dateStart      =   DateTime.Parse(_date,CultureInfo.InvariantCulture);
                        }
                        catch (Exception ex)
                        {
                            string msg      =   string.Format("[E]ADNEncryptedLicense Ctor Bad DateStart: {0}, ex: {1}", str, ex);
                            if ( LicenseTraceSwitch.Sw.TraceError )
                                Trace.WriteLine( msg,LicenseTraceSwitch.Sw.Info);
                            throw new LicenseException(type, null, msg,ex);
                        }
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor Date: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
					case 7:
						_company	        =   str;
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor Company: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
					case 8:
						_PIN		        =	str;
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor PIN: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
					case 9:
                        try
                        {
						    _monthsLimit	=	Int32.Parse(str, CultureInfo.InvariantCulture);
						    _dateLimit		=   _dateStart.AddMonths(_monthsLimit);
                        }
                        catch (Exception ex)
                        {
                            string msg      =  string.Format("[E]ADNEncryptedLicense Ctor Bad MonthsLimit: {0}, ex: {1}", str, ex);
                            if ( LicenseTraceSwitch.Sw.TraceError )
                                Trace.WriteLine( msg,LicenseTraceSwitch.Sw.Info);
                            throw new LicenseException(type, null, msg,ex);
                        }
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor MonthsLimit: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
                    case 10:
                        try
                        {
                            _usageLimit     =   Int32.Parse(str, CultureInfo.InvariantCulture);
                        }
                        catch (Exception ex)
                        {
                            string msg      =  string.Format("[E]ADNEncryptedLicense Ctor Bad UsageLimit: {0}, ex: {1}", str, ex);
                            if ( LicenseTraceSwitch.Sw.TraceError )
                                Trace.WriteLine( msg,LicenseTraceSwitch.Sw.Info);
                            throw new LicenseException(type, null, msg,ex);
                        }
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense UsageLimit: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
                    case 11:
                        try
                        {
                            _NbUsers        =   Int32.Parse(str, CultureInfo.InvariantCulture);
                        }
                        catch (Exception ex)
                        {
                            string msg      =  string.Format("[E]ADNEncryptedLicense Ctor Bad NbUSers: {0}, ex: {1}", str, ex);
                            if ( LicenseTraceSwitch.Sw.TraceError )
                                Trace.WriteLine( msg,LicenseTraceSwitch.Sw.Info);
                            throw new LicenseException(type, null, msg,ex);
                        }
                        if ( LicenseTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense Ctor NbUSers: {0}", str),LicenseTraceSwitch.Sw.Info);
                        break;
                }

			}
		}

        public bool IsCrmOk
        {
            get
            {
                int nbU = OnExternalLicenseCountEvent(this);
                return (nbU <= NbUsers);
            }
        }

        
        public bool IsRunExpired
        {
            get
            {
                return (UsageCount > UsageLimit);
            }
        }

        public bool IsTimeExpired
        {
            get
            {
                DateTime wdate = DateTime.Now.Date;
                return (wdate > DateLimit);
            }
        }

        public virtual void IncrementUsageCounter() 
		{
			_usageCount++;
            if ( LicenseTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNEncryptedLicense IncrementUsageCounter _usageCount: {0}", _usageCount),LicenseTraceSwitch.Sw.Info);
        }
	}
	
	public class ExpiringLicense : ADNEncryptedLicense 
	{

		public ExpiringLicense(Type type, string key) : base(type, key) 
		{
		}

		public bool IsExpired 
		{
			get 
			{
				return ( IsTimeExpired || IsRunExpired );
			}
		}

	}


}
